package com.epoint.utils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.tokenizer.Result;

/**
 * sql查询的工具类
 * 
 * @author 梁卓
 *
 */
public class SQLUtil {	
    
	/**
	 * 通过反射获取对象信息 【调用前一定要使用while(rs.next()) {调用该方法，传入rs} , 否之报错】
	 * @param clazz class
	 * @param rs sql结果
	 * @return 对象信息
	 */
	public static <T> T queryObjectInfo(Class<T> clazz, ResultSet rs) {
	    // 获取所有对象中的字段
	    Field[] fields = clazz.getDeclaredFields();
	    
	    T newInstance = null;
	    
	    try {
	        // 获取所有sql返回的字段集合
	        ResultSetMetaData metaData = rs.getMetaData();
	        HashSet<String> sqlFieldSet = new HashSet<>();
	        for (int i = 1; i <= metaData.getColumnCount(); i++) {
	            sqlFieldSet.add(metaData.getColumnName(i));
	        }
	        
	        // 创建实例化对象
	        newInstance = clazz.newInstance();
	       
	        for(Field field : fields) {
	            // 字段名全为小写
                String lowFieldName = field.getName().toLowerCase();
                
                if (!sqlFieldSet.contains(lowFieldName)) {
                    System.out.println("本对象中的该字段（"+lowFieldName+"）不在sql返回的字段之中");
                    continue;
                }
	            // 设置访问权限
	            field.setAccessible(true);
	            if (field.getType() == String.class) {
	                field.set(newInstance, rs.getString(lowFieldName));
	            } else if (field.getType() == Integer.class) {
	                field.set(newInstance, rs.getInt(lowFieldName));
	            } else if (field.getType() == Date.class) {
	                field.set(newInstance, rs.getTimestamp(lowFieldName));
	            } else if (field.getType() == Double.class) {
	                field.set(newInstance, rs.getDouble(lowFieldName));
	            }
	        }
	    } catch (Exception e) {
	        e.printStackTrace();
            System.out.println("获取对象信息错误！");
        }
	    
	    return newInstance;
	    
	}
	
	
	/**
	 * insert语句中设置？中的值【注：sql字段顺序要和对象字段顺序一致，否则导致字段插入顺序错误】
	 * @param clazz class文件对象
	 * @param ps PreparedStatement
	 * @return 结果
	 */
	public static <T> PreparedStatement insertObjectInfo(T obj, PreparedStatement ps) {
	    // 获取所有字段
        Field[] fields = obj.getClass().getDeclaredFields();
        int i = 1;
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Object fieldValue = field.get(obj);
                // 如果属性值不为空再设置值(允许空值的字段，sql中可设置为默认值)
                if (ObjectUtil.isNotNull(fieldValue)) {
                    if (fieldValue instanceof String) {
                        ps.setString(i, (String) fieldValue);
                    } else if (fieldValue instanceof Integer) {
                        ps.setInt(i, (Integer) fieldValue);
                    } else if (fieldValue instanceof Date) {
                        ps.setObject(i, fieldValue);
                    } else if (fieldValue instanceof Double) {
                        ps.setDouble(i, (Double) fieldValue);
                    }
                    i++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("设置对象信息错误！");
        }
        
	    return ps;
	}
	
	
	/**
     * update语句中设置？中的值【注：sql字段顺序要和对象字段顺序可不必一致】
     * @param clazz class文件对象
     * @param ps PreparedStatement
     * @return 结果
     */
    public static <T> PreparedStatement updateObjectInfo(T obj, List<String> sqlFieldList, PreparedStatement ps) {
        // 获取所有字段
        Field[] fields = obj.getClass().getDeclaredFields();
        int i = 1;
        try {
            // sql字段顺序和设置值的顺序要一致
            for(String sqlField : sqlFieldList) {
                for (Field field : fields) {
                    
                    if (sqlField.equals(field.getName().toLowerCase())) {
                        field.setAccessible(true);
                        Object fieldValue = field.get(obj);
                        // 如果属性值不为空再设置值(允许空值的字段，sql中可设置为默认值)
                        if (ObjectUtil.isNotNull(fieldValue)) {
                            if (fieldValue instanceof String) {
                                ps.setString(i, (String) fieldValue);
                            } else if (fieldValue instanceof Integer) {
                                ps.setInt(i, (Integer) fieldValue);
                            } else if (fieldValue instanceof Date) {
                                ps.setObject(i, fieldValue);
                            } else if (fieldValue instanceof Double) {
                                ps.setDouble(i, (Double) fieldValue);
                            }
                            i++;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("设置对象信息错误！");
        }
        
        return ps;
    }

}
